package com.elasticsearch.config;

import lombok.Data;
import lombok.EqualsAndHashCode;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.elasticsearch.client.ClientConfiguration;
import org.springframework.data.elasticsearch.client.RestClients;
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
import org.springframework.util.StringUtils;


/**
 * elasticsearch配置
 *
 * @author Amadeus
 * @date 2023/06/26
 */
@Data
@EqualsAndHashCode(callSuper = true)
@ConfigurationProperties(prefix = "spring.elasticsearch.rest")
@EnableElasticsearchRepositories(basePackages = {"com.elasticsearch.repository"})
@Configuration
public class ElasticsearchConfig extends AbstractElasticsearchConfiguration {

    private String uris;
    private String host;
    private Integer port;
    private String userName;
    private String password;
    private Boolean local;
    private Long timeout;

    private static Logger log = LoggerFactory.getLogger(ElasticsearchConfig.class);

    @Override
    public RestHighLevelClient elasticsearchClient() {
        log.info("userName:{}", userName);
        if (Boolean.FALSE.equals(local)) {
            final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
            credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(userName, password));
            RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, "http"))
                    .setHttpClientConfigCallback(httpClientBuilder ->
                            httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
            return new RestHighLevelClient(builder);
        }

        ClientConfiguration.TerminalClientConfigurationBuilder terminalClientConfigurationBuilder = ClientConfiguration.builder()
                .connectedTo(uris).withSocketTimeout(timeout);
        if (!StringUtils.isEmpty(userName)) {
            terminalClientConfigurationBuilder.withBasicAuth(userName, password);
        }
        ClientConfiguration clientConfiguration = terminalClientConfigurationBuilder
                .build();
        return RestClients.create(clientConfiguration).rest();
    }

    @Bean
    public ElasticsearchRestTemplate restTemplate() {
        RestHighLevelClient restHighLevelClient = this.elasticsearchClient();
        return new ElasticsearchRestTemplate(restHighLevelClient);
    }
}